package com.share.tools;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.TimeUnit;

/**
 * @desc: redis锁 高并发场景可以考虑redisson
 * @author:caifan
 * @date:2020/4/19
 */
@Slf4j
public class RedisLockUtils {

    /**
     * tryLock 默认过期时间秒， 高并发场景可以使用锁续命（定时任务每隔指定时间重新加锁设置时间）
     *
     * @param redisTemplate
     * @param key
     * @param expireTime
     * @return
     */
    public static boolean tryLock(RedisTemplate redisTemplate, String key, String clientId, Long expireTime) {
        return tryLock(redisTemplate, key, clientId, expireTime, TimeUnit.SECONDS);
    }

    /**
     *
     * @param redisTemplate
     * @param key
     * @param clientId UUID.randomUUID().toString() 防止高并发情况下相同的key被不同锁删除
     * @param expireTime
     * @param timeUnit
     * @return
     */
    public static boolean tryLock(RedisTemplate redisTemplate, String key, String clientId, Long expireTime, TimeUnit timeUnit) {
        Boolean success = redisTemplate.opsForValue().setIfAbsent(key, clientId, expireTime, timeUnit);
        log.info("tryLock key = {}, value = {}, expireTime = {}", key, clientId, expireTime);
        return success != null && success;
    }


    /**
     * unLock
     *
     * @param redisTemplate
     * @param key
     * @return
     */
    public static boolean unLock(RedisTemplate redisTemplate, String key, String clientId) {
        Boolean success = false;
        if (clientId.equals(redisTemplate.opsForValue().get(key))) {
            success = redisTemplate.delete(key);
        }
        log.info("unLock key = {}", key);
        return success;
    }

}
